package com.lzq.rabbitmqdemo.java_api.rpc;

import com.lzq.rabbitmqdemo.java_api.constant.ConnectionConfig;
import com.lzq.rabbitmqdemo.java_api.constant.Constants;
import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class RPCClient {
    public static void main(String[] args) throws Exception{
        ConnectionFactory factory = ConnectionConfig.getFactory();
        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {
            channel.queueDeclare(Constants.RPC_REQUEST_QUEUE_NAME, true, false, false, null);
            //唯⼀标志本次请求
            String corrId = UUID.randomUUID().toString();
            //定义临时队列，并返回⽣成的队列名称
            String replyQueueName = channel.queueDeclare().getQueue();
            // ⽣成发送消息的属性
            AMQP.BasicProperties props = new AMQP.BasicProperties
                    .Builder()
                    .correlationId(corrId) // 唯⼀标志本次请求
                    .replyTo(replyQueueName) // 设置回调队列
                    .build();
            //通过内置交换机, 发送消息
            String message = "hello rpc...";
            channel.basicPublish("", Constants.RPC_REQUEST_QUEUE_NAME, props, message.getBytes());
            //阻塞队列，⽤于存储回调结果
            final BlockingQueue<String> response = new ArrayBlockingQueue<>(1);
            //接收服务端的响应
            DefaultConsumer consumer = new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope,
                                           AMQP.BasicProperties properties, byte[] body) throws IOException {
                    System.out.println("接收到回调消息:" + new String(body));
                    if (properties.getCorrelationId().equals(corrId)) {
                        response.offer(new String(body, "UTF-8"));
                    }
                }
            };
            channel.basicConsume(replyQueueName,true,consumer);
            //获取回调的结果
            String result = response.take();
            System.out.println(" [RPCClient] Result:"+result);
        }
    }
}
